/* eslint no-param-reassign:off, camelcase:off,no-console:off, no-alert: off */
/**
 * @author: 邓子强
 * @Date: 2020/5/23
 * @class Canvas Canvas操作类
 */

export class Canvas {
    constructor(ctx) {
        if (ctx.getContext) {
            this.canvas = ctx;
            this.ctx = ctx.getContext('2d');
            console.log('Canvas constructor');
        } else {
            alert('canvas-unsupported');
        }
    }

    get() {
        return this.ctx;
    }

    getCanvas() {
        return this.canvas;
    }

    set(ctx) {
        this.ctx = ctx;
    }

    /**
     * @function drawLine 绘制线条
     */
    onDrawLine({
        start_x = 0,
        start_y = 0,
        end_x = 0,
        end_y = 0,
        weight = 1,
        color = '#FFFFFF',
        lineCap = 'round',
    }) {
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.moveTo(start_x, start_y);
        this.ctx.lineTo(end_x, end_y);
        this.ctx.lineCap = lineCap;
        this.ctx.lineWidth = weight;
        this.ctx.strokeStyle = color;
        this.ctx.stroke(); // 绘制路径
        this.ctx.restore();
        return this.ctx;
    }

    /**
     * @function drawPolygon 绘制多边形
     * @param points 顶点数组
     * @param color 颜色
     * @param mode 模式
     */
    onDrawPolygon({ points = [], color = '#000000', mode }) {
        this.ctx.save();
        // 开始绘制
        if (points.length > 1) {
            this.ctx.beginPath();
            points.forEach((point, i) => {
                if (i === 0) {
                    this.ctx.moveTo(points[0].x, points[0].y);
                } else {
                    this.ctx.lineTo(point.x, point.y);
                }
            });
            this.ctx.closePath();
        }
        this.ctx.fillStyle = color;
        mode === 'fill' && this.ctx.fill();
        mode === 'stroke' && this.ctx.stroke();
        this.ctx.restore();
        return this.ctx;
    }

    /**
     * 绘制矩形
     * @param start_x
     * @param start_y
     * @param width
     * @param height
     * @param bgColor
     * @param borderRadius
     * @param mode
     * @param lineWidth
     */
    onFillRect({
        start_x = 0,
        start_y = 0,
        width = 0,
        height = 0,
        bgColor = '#000000',
        borderRadius = 0,
        mode = 'fill',
        lineWidth = 1,
    }) {
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.moveTo(start_x + borderRadius, start_y);
        this.ctx.lineTo(start_x + width - borderRadius, start_y);
        this.ctx.arcTo(
            start_x + width,
            start_y,
            start_x + width,
            start_y + borderRadius,
            borderRadius
        );
        this.ctx.lineTo(start_x + width, start_y + height - borderRadius);
        this.ctx.arcTo(
            start_x + width,
            start_y + height,
            start_x + width - borderRadius,
            start_y + height,
            borderRadius
        );
        this.ctx.lineTo(start_x + borderRadius, start_y + height);
        this.ctx.arcTo(
            start_x,
            start_y + height,
            start_x,
            start_y + height - borderRadius,
            borderRadius
        );
        this.ctx.lineTo(start_x, start_y + borderRadius);
        this.ctx.arcTo(start_x, start_y, start_x + borderRadius, start_y, borderRadius);
        this.ctx.closePath();
        this.ctx.fillStyle = bgColor;
        this.ctx.lineWidth = lineWidth;
        mode === 'fill' && this.ctx.fill();
        mode === 'stroke' && this.ctx.stroke();
        this.ctx.restore();
        return this.ctx;
    }

    /**
     * 绘制文本
     * @param text
     * @param x
     * @param y
     * @param height
     * @param fontSize
     * @param fontWeight
     * @param color
     * @returns {*}
     */
    onFillText({
        text = '',
        x = 0,
        y = 0,
        maxWidth = undefined,
        fontSize = '16px',
        fontWeight = 'normal',
        color = '#000000',
        textAlign = 'start',
    }) {
        this.ctx.save();
        this.ctx.textAlign = textAlign;
        this.ctx.font = `normal normal ${fontWeight} ${fontSize} sans-serif`;
        this.ctx.fillStyle = color;
        this.ctx.fillText(text, x, y, maxWidth);
        this.ctx.restore();
        return this.ctx;
    }

    onDrawImage({
        img = new Image(),
        x = 0,
        y = 0,
        width = undefined,
        height = undefined,
        sx = undefined,
        sy = undefined,
        sWidth = undefined,
        sHeight = undefined,
    }) {
        this.ctx.globalCompositeOperation = 'source-over';
        const draw = (imgObj) => {
            if (sx !== undefined && sy !== undefined) {
                this.ctx.drawImage(
                    imgObj,
                    sx,
                    sy,
                    sWidth || width,
                    sHeight || height,
                    x,
                    y,
                    width,
                    height
                );
            } else if (width !== undefined && height !== undefined) {
                this.ctx.drawImage(imgObj, x, y, width, height);
            } else {
                this.ctx.drawImage(imgObj, x, y);
            }
        };
        if (typeof img === 'string') {
            const image = new Image();
            image.src = img;
            image.onload = () => {
                draw(image);
            };
        } else {
            img.onload = () => {
                draw(img);
            };
            draw(img);
        }
        return this.ctx;
    }

    onClearRect(x, y, w, h) {
        this.ctx.clearRect(x, y, w, h);
        return this.ctx;
    }
}
